﻿using System;
using System.Collections.Generic;
using System.Diagnostics;

using Microsoft.WowAddonStudio.Lua.AST;
using Microsoft.WowAddonStudio.Lua.Model;
using Microsoft.WowAddonStudio.Lua.Support;

namespace Microsoft.WowAddonStudio.Lua.Parser
{
    public class QualifiedNameParserSink : ParserSink
    {
        private readonly List<QualifiedName> qualifiedNames = new List<QualifiedName>();

        /// <summary>
        /// Initializes a new instance of the <see cref="QualifiedNameParserSink"/> class.
        /// </summary>
        public QualifiedNameParserSink()
        {
            this.FindNames = true;
        }

        /// <summary>
        /// Starts the name.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="name">The name.</param>
        public override void StartName(LexLocation location, string name)
        {
            Trace.WriteLine(String.Format("StartName: {0} ({1})", name, location));
            qualifiedNames.Add(new QualifiedName(new Identifier(location)
                                                 {
                                                     Name = name
                                                 }));
        }

        /// <summary>
        /// Qualifies the name.
        /// </summary>
        /// <param name="selectorLocation">The selector location.</param>
        /// <param name="nameLocation">The name location.</param>
        /// <param name="name">The name.</param>
        public override void QualifyName(LexLocation selectorLocation, LexLocation nameLocation, string name)
        {
            Trace.WriteLine(String.Format("QualifyName: {0} ({1})", name, nameLocation));

            // Further qualify the name of the last qualified name added
            if (qualifiedNames.Count > 0)
            {
                qualifiedNames[qualifiedNames.Count - 1] = qualifiedNames[qualifiedNames.Count - 1].Qualify(new Identifier(nameLocation)
                                                                                                            {
                                                                                                                Name = name
                                                                                                            });
            }
        }

        /// <summary>
        /// Gets the qualified names.
        /// </summary>
        public IEnumerable<QualifiedName> QualifiedNames
        {
            get { return qualifiedNames; }
        }

        /// <summary>
        /// Gets the qualified name at the given position.
        /// </summary>
        /// <param name="line">The line index.</param>
        /// <param name="column">The column index.</param>
        /// <returns>An instance of the <see cref="QualifiedName"/> if found; null otherwise.</returns>
        public QualifiedName GetQualifiedName(int line, int column)
        {
            foreach (var qualifiedName in qualifiedNames)
            {
                if (qualifiedName.Location.Contains(line, column))
                    return qualifiedName;
            }

            return null;
        }

        public QualifiedName GetLastQualifiedName(int line, int column)
        {
            QualifiedName lastQualifiedName = null;

            foreach (var qualifiedName in qualifiedNames)
            {
                if (qualifiedName.Location.Before(line, column) && qualifiedName.Location.Line == line)
                    lastQualifiedName = qualifiedName;

                if (qualifiedName.Location.After(line, column))
                    break;
            }

            return lastQualifiedName;
            
        }
    }
}